package com.project.util;

import java.util.regex.Pattern;

import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.project.entity.Account;
import com.project.entity.Staff;
import com.project.ryudo.SessionBean.AccountBeanRemote;
import com.project.ryudo.SessionBean.StaffBeanRemote;
import com.project.ryudo.SessionBean.requestPropertyBeanRemote;
import com.project.tructc.MBean.MAccount;





public class MyPhaseListener implements PhaseListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1776885664304905664L;
	final private static String GUEST_VIEW = "GUEST_VIEW";
	final private static String USER_VIEW = "USER_VIEW";
	final private static String STAFF_VIEW = "STAFF_VIEW";
	final private static String LOGIN_VIEW = "LOGIN_VIEW";
	final private static String REGISTRATION_VIEW = "REGISTRATION_VIEW";
	final private static String FORGOT_PASSWORD_VIEW = "FORGOT_PASSWORD_VIEW";
	final private static String STAFF_LOGIN_VIEW = "STAFF_LOGIN_VIEW";
	@Override
	public void afterPhase(PhaseEvent arg0) {
		FacesContext fc = FacesContext.getCurrentInstance();
	    String url = fc.getViewRoot().getViewId();
	    
		String management_url = ".+management[\\W].+";
		String staff_url = ".+admin[\\W].+";
		String guest_url = ".+front[\\W].+";
		String login_url = ".+front[\\W]login.xhtml";
		String registration_url = ".+front[\\W]registration.xhtml";
		String forgot_pass_url = ".+front[\\W]forgot_password.xhtml";
		
		String staff_login_url = ".+admin[\\W]login_staff.xhtml";
		String current_view = GUEST_VIEW;
		if(url != null)
		{
			if(Pattern.matches(management_url,url))
			{
				current_view = USER_VIEW;
			} else if(Pattern.matches(staff_url,url))
			{
				current_view = STAFF_VIEW;
				
			}  
			else if(Pattern.matches(login_url,url)){
				current_view = LOGIN_VIEW;
			} 
			else if(Pattern.matches(registration_url,url))
			{
				current_view = REGISTRATION_VIEW;
				
			} else if(Pattern.matches(forgot_pass_url,url))
			{
				current_view = FORGOT_PASSWORD_VIEW;
			} else if(Pattern.matches(guest_url,url))
			{
				current_view = GUEST_VIEW;
			} else if(Pattern.matches(staff_login_url, url))
			{
				current_view = STAFF_LOGIN_VIEW;
			}
		}
		
		
			HttpServletRequest req = (HttpServletRequest) fc.getExternalContext().getRequest();
			HttpServletResponse res = (HttpServletResponse) fc.getExternalContext().getResponse();
			String checkType = user_logged_in();  
			String checkStaff = staff_logged_in();
			try {
				compare_account_session();
			} catch (NamingException e) {
				
			}
			if (current_view.equalsIgnoreCase(USER_VIEW) || current_view.equalsIgnoreCase(STAFF_VIEW)) {
		           if(current_view.equalsIgnoreCase(USER_VIEW))
		           {
		               if (checkType.equals("guest")) //Kick the user to the login page
		               {
		                   NavigationHandler nh = fc.getApplication().getNavigationHandler();
		                   nh.handleNavigation(fc, null, "redirect_login_user");
		               }
		               check_status_user(); // Kick user with status = false to not_allowed page !
	           	   }
		           if(current_view.equalsIgnoreCase(STAFF_VIEW) && !Pattern.matches(staff_login_url, url))
		           {
		        	   if (!checkStaff.equals("STAFF")) //Kick the user to the login page
		               {
		                   NavigationHandler nh = fc.getApplication().getNavigationHandler();
		                   nh.handleNavigation(fc, null, "redirect_login_staff");
		               }
		        	   check_status_staff();
		           }
		           if(current_view.equalsIgnoreCase(STAFF_VIEW) && Pattern.matches(staff_login_url, url))
		           {
		        	   if (checkStaff.equals("STAFF")) //Kick the user to the login page
		               {
		                   NavigationHandler nh = fc.getApplication().getNavigationHandler();
		                   nh.handleNavigation(fc, null, "redirect_logged_staff");
		               }
		        	   
		           }
	
	        } 
			if(current_view.equalsIgnoreCase(REGISTRATION_VIEW) || current_view.equalsIgnoreCase(FORGOT_PASSWORD_VIEW) || current_view.equalsIgnoreCase(LOGIN_VIEW))
			{
				if(checkType.equals("USER"))
				{
					NavigationHandler nh = fc.getApplication().getNavigationHandler();
	                nh.handleNavigation(fc, null, "redirect_logged_user");
				}
			}
			
		
	}

	@Override
	public void beforePhase(PhaseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	private String user_logged_in() 
	{
		 HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
         Object mAcc = req.getSession().getAttribute("mAccount");
         String re = "";
         
         if(mAcc instanceof MAccount && ((MAccount)mAcc != null) && ((MAccount)mAcc).getAcc().getEmail() != null)
         {
        	 re = "USER";
         } 
         else
         {
        	 re = "guest";
         }
         return re;
    }
	
	private String staff_logged_in()
	{
		HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        MAccount mAcc2 = (MAccount)req.getSession().getAttribute("mAccount");
        String reStaff = "";
		 if(mAcc2 != null && mAcc2.getStf().getEmail() != null)
         {
			 reStaff = "STAFF";
         } 
		 else
         {
			 reStaff = "";
         }
		 return reStaff;
	}
	
	
	public void compare_account_session() throws NamingException
	{
		HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        MAccount mAcc3 = (MAccount)req.getSession().getAttribute("mAccount");
        if(mAcc3 != null && mAcc3.getAcc().getEmail() != null)
        {
        	Context ctx = new InitialContext();
        	AccountBeanRemote requestUser = (AccountBeanRemote) ctx
					.lookup("MySweetHome/AccountBean/remote");
        	Account accRequest = (Account)requestUser.loadRequestedUser(String.valueOf(mAcc3.getAcc().getAccID())).get(0);
        	if(accRequest.getIsVerified() != mAcc3.getAcc().getIsVerified() || accRequest.getStatus() != mAcc3.getAcc().getStatus())
        	{
        		mAcc3.setAcc(accRequest);
        	}
        }
        if(mAcc3 != null && mAcc3.getStf().getEmail() != null)
        {
        	Context ctx = new InitialContext();
        	StaffBeanRemote requestUser = (StaffBeanRemote) ctx
					.lookup("MySweetHome/StaffBean/remote");
        	Staff stfRequest = (Staff)requestUser.requestedStaff(mAcc3.getStf().getEmail()).get(0);
        	if(stfRequest.isAdmin() != mAcc3.getStf().isAdmin() || stfRequest.isStatus() != mAcc3.getStf().isStatus())
        	{
        		mAcc3.setStf(stfRequest);
        	}
        }
	}
	
	public void check_status_user()
	{
		FacesContext fc = FacesContext.getCurrentInstance();
		HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        MAccount mAcc3 = (MAccount)req.getSession().getAttribute("mAccount");
		if(mAcc3 != null && mAcc3.getAcc().getEmail() != null && mAcc3.getAcc().getStatus() == false)
		{
			NavigationHandler nh = fc.getApplication().getNavigationHandler();
            nh.handleNavigation(fc, null, "not_allowed");
		}
	}
	
	public void check_status_staff()
	{
		FacesContext fc = FacesContext.getCurrentInstance();
		HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        MAccount mAcc4 = (MAccount)req.getSession().getAttribute("mAccount");
		if(mAcc4 != null && mAcc4.getStf().getEmail() != null && mAcc4.getStf().isStatus() == false)
		{
			mAcc4.LogoutStaff();
			NavigationHandler nh = fc.getApplication().getNavigationHandler();
            nh.handleNavigation(fc, null, "not_allowed_staff");
		}
	}
	
	@Override
	public PhaseId getPhaseId() {
		return PhaseId.RESTORE_VIEW;
	}

}
